I keep most of my stuff under source control, but sometimes I need to keep an actual backup of a file because of the circumstances in which it is created or used.
I have a bash script that I use for this which keeps a rolling 3 backup copies of the file, so each time it is run providing the file has changed it moves copy 2 to copy 3 and copy 1 to copy 2 copy and then copies the actual file to copy 1 etc.
#!/bin/bash
if [ -z "${1}" ]
then echo "Please input something"
exit 1
fi
fileExists(){
if [ -d "${1}" ]
then echo "${1} is a directory"
return 1
elif [ -f "${1}" ]
then return 0
else echo "${1} is not valid"
return 1
fi
}
FILENAME=${1}
if fileExists ${FILENAME}
then echo "Backing up file ${FILENAME}"
else echo cannot backup ${FILENAME}
exit 1
fi
echo Checking if file is same as existing backup
if [ -e "${FILENAME}" ]; then
if [ -e "${FILENAME}-1" ]; then
SHA1=`sha1sum ${FILENAME} | awk '{print $1;}'`
SHA1BK1=`sha1sum ${FILENAME}-1 | awk '{print $1;}'`
if [ "${SHA1}" = "${SHA1BK1}" ]; then
echo "Nothing has changed ${SHA1} versus ${SHA1BK1}"
exit 1
fi
fi
fi
# archive existing tars
if [ -e "${FILENAME}" ]; then
for a in 2 1
do
let b="${a}+1"
if [ -e "${FILENAME}-${b}" ]; then
rm "${FILENAME}-${b}"
fi
if [ -e "${FILENAME}-${a}" ]; then
mv "$FILENAME-${a}" "$FILENAME-${b}"
fi
done
cp "${FILENAME}" "${FILENAME}-1"
fi
echo "backup completed"
exit 0
The script first checks (top of script) to see that a file name was specified on the input line.
Then we have defined a fileExists function that checks a file is a valid file.
It checks we have a valid file by calling the above fileExists function using the filename passed in when the script is run.
It then compares using a checksum to see if the file is different from current latest backup.
If it is different then it loops through moving previous copies to a later version and finally copying the file to the latest backup.